package Function;

import FCRendering.FCRMaster;
import VWorldGameStudio.FCPlayerInfo;
import VWorldGameStudio.FCPropulsion;
import socket.FCRSocketClient;
import socket.FCRSocketServer;
import socket.util.ByteUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

import static FCRendering.FCRMaster.fcv;
import static FCRendering.FCRMaster.player1;

public class FCMutilPlayPropulsionCache {

    /**
     * 所有想要共享给其他玩家看的东西镜像
     * key 是地图名称
     */
    public static ConcurrentHashMap<String, CopyOnWriteArrayList<FCPropulsion>> mapToPropulsionMap = new ConcurrentHashMap<>();

    /**
     * key是FCPropulsion的hostId+"@"+name, val 是地图名称，就是为了快速去操纵mapToPropulsionMap增减改
     */
    public static ConcurrentHashMap<String, FCPropulsion> propulsioMap = new ConcurrentHashMap<>();


    private static void insertPropulsionMap(FCPropulsion fcPropulsion){
        CopyOnWriteArrayList<FCPropulsion> has = mapToPropulsionMap.get(fcPropulsion.getOldMapName());
        if(has == null){
            has = new CopyOnWriteArrayList<>();
            mapToPropulsionMap.put(fcPropulsion.getOldMapName(), has);
        }
        has.add(fcPropulsion);
    }

    //TODO 更新显示在地图上的镜像，比如propusion的地图变化了就调用一次
    public static void shareIt(FCPropulsion fcPropulsion){
        FCPropulsion old = propulsioMap.get(fcPropulsion.getPropulsionHostId()+"@"+fcPropulsion.getPropulsionName());
        if(old == null){
            //如果
            propulsioMap.put(fcPropulsion.getPropulsionHostId()+"@"+fcPropulsion.getPropulsionName(), fcPropulsion);
            fcPropulsion.setOldMapName(fcPropulsion.getPmapname());
            insertPropulsionMap(fcPropulsion);
        }else {
            if(!fcPropulsion.getOldMapName().equals(fcPropulsion.getPmapname())){
                CopyOnWriteArrayList<FCPropulsion> has = mapToPropulsionMap.get(fcPropulsion.getOldMapName());
                has.remove(fcPropulsion);//移出去
                fcPropulsion.setOldMapName(fcPropulsion.getPmapname());
                insertPropulsionMap(fcPropulsion);
            }
        }
    }

    //表示本地的坦克要在地图上显示了或更新位置，可以重复调用不会存在重复同样坦克的
    public static void loacalShareIt(FCPropulsion fcPropulsion){
        shareIt(fcPropulsion);
        if (fcv.isSever()) {
            FCRSocketServer.getIn().syncFCPropulsion(fcPropulsion);
        } else if (fcv.isClient()) {
            FCRSocketClient.getIn().syncFCPropulsion(fcPropulsion);
        }
    }


    /**
     * @param fcPropulsion
     */
    //表示本地的坦克不要在地图上显示了，本地的极少用，只有出租车回收后用到，普通的已经获取的不用
    public static void loacalNoShareIt(FCPropulsion fcPropulsion){
        FCPropulsion old = propulsioMap.get(fcPropulsion.getPropulsionHostId()+"@"+fcPropulsion.getPropulsionName());
        if(old != null){
            CopyOnWriteArrayList<FCPropulsion> has = mapToPropulsionMap.get(fcPropulsion.getOldMapName());
            if(has != null){
                has.remove(fcPropulsion);
                propulsioMap.remove(fcPropulsion.getPropulsionHostId()+"@"+fcPropulsion.getPropulsionName());
            }

            if (fcv.isSever()) {
                FCRSocketServer.getIn().syncFCPropulsion(fcPropulsion);
            } else if (fcv.isClient()) {
                FCRSocketClient.getIn().syncFCPropulsion(fcPropulsion);
            }
        }
    }

    /**
     * @param params 这里只更新了位置，显示功能而儿
     */
    public static void fromNetShareIt(byte[] params, boolean addInTeam){
        int offset = 0;
        while (true) {
            int len = ByteUtil.getInt(new byte[]{params[0 + offset], params[1 + offset], params[2 + offset], params[3 + offset]});
            byte[] p1 = new byte[len];
            System.arraycopy(params, 4 + offset, p1, 0, len);
            offset += len + 4;
            String pdata = new String(p1);
            String[] pSplits = pdata.split(",");
            FCPropulsion searchOne = FCRMaster.tankLib.getTankOfID(pSplits[1],pSplits[2]);
            if(searchOne != null){
                searchOne.setPmapname(pSplits[0]);
                searchOne.setPcoorX(Integer.parseInt(pSplits[4]));
                searchOne.setPcoorY(Integer.parseInt(pSplits[5]));
                searchOne.setPPianYiX(Integer.parseInt(pSplits[6]));
                searchOne.setPPianYiY(Integer.parseInt(pSplits[7]));
                searchOne.setBeingTow(Integer.parseInt(pSplits[8]));
                searchOne.setPdir(Integer.parseInt(pSplits[9]));
                searchOne.setPactionNum(Integer.parseInt(pSplits[10]));
                searchOne.setVisable(Integer.parseInt(pSplits[11]));
                shareIt(searchOne);
                if(addInTeam){
                    player1.addRemotePropulsion(searchOne);
                }
                System.out.println("searchOne "+searchOne.getSaveString()+" size:"+propulsioMap.size());
            }else {
                System.out.println("坦克数据还没同步创建所以找不到");
            }

            if(params.length == offset){
                break;
            }
        }
    }

    /**
     * 刪除需要去除的共顯對象
     * @param targetHostId
     */
    public static void fromNetNoShareIt(String targetHostId){
        ArrayList<Map.Entry<String, FCPropulsion>> removables = new ArrayList<>(1);
        Iterator<Map.Entry<String, FCPropulsion>> iterator = propulsioMap.entrySet().iterator();
        while (iterator.hasNext()){
            Map.Entry<String, FCPropulsion> entry = iterator.next();
            String hostid = entry.getKey().split("@")[0];
            if(hostid.equals(targetHostId)){
                removables.add(entry);
            }
        }
        for(Map.Entry<String, FCPropulsion> entry: removables){
            FCPropulsion fcPropulsion = entry.getValue();
            CopyOnWriteArrayList<FCPropulsion> has = mapToPropulsionMap.get(fcPropulsion.getOldMapName());
            if(has != null){
                has.remove(fcPropulsion);
            }
            propulsioMap.remove(entry.getKey());
        }
    }
}
